﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DiskClean
{
    internal class DiskManager
    {
        public DiskManager()
        {
        }
        // 获取所有盘符
        public List<string> GetAllDrives()
        {
            List<string> drives = new List<string>();
            foreach (DriveInfo drive in DriveInfo.GetDrives())
            {
                if (drive.IsReady)
                {
                    drives.Add(drive.Name);
                }
            }
            return drives;
        }
        // 获取指定盘符的磁盘信息
        // 递归遍历指定盘符下的所有文件，并按照大小倒序排列
        public List<FileInfo> GetFilesByDrive(string driveLetter,Dictionary<string,bool> filterDict,Common.Options options)
        {
            List<FileInfo> files = new List<FileInfo>();
            try
            {
                if (Directory.Exists(driveLetter))
                {
                    // 递归遍历指定盘符下的所有文件
                    Stopwatch stopwatch = new Stopwatch();
                    stopwatch.Start();
                    PreScanDisk(driveLetter, files,filterDict,options);
                    //RecursiveGetFiles(new DirectoryInfo(driveLetter), files);
                    stopwatch.Stop();
                    Console.WriteLine("获取文件用时: " + stopwatch.ElapsedMilliseconds + " 毫秒");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("获取文件时出错: " + ex.Message);
            }

            // 按照文件大小倒序排列
            files = files.OrderByDescending(f => f.Length).ToList();
            return files;
        }

        // 递归方法，用于遍历目录并收集文件信息
        private void RecursiveGetFiles(DirectoryInfo directory, List<FileInfo> files,Common.Options options)
        {
            // 获取当前目录下的所有文件并添加到列表中
            try
            {
                int count = directory.GetFiles().Length;
                int dircount = directory.GetDirectories().Length;
                if ((count + dircount == 0)&&options.IsDeletEmptyDir)
                {
                    Directory.Delete(directory.FullName);
                    return;
                }
            }catch(Exception ex)
            {
                Console.WriteLine("遍历目录时出错: " + ex.Message);
                return;
            }
            files.AddRange(directory.GetFiles());

            // 获取当前目录下的所有子目录
            DirectoryInfo[] subDirectories = directory.GetDirectories();

            // 递归遍历每个子目录
            foreach (DirectoryInfo subDirectory in subDirectories)
            {
                RecursiveGetFiles(subDirectory, files,options);
            }
        }
        private bool IsFilterDir(string dirName,Dictionary<string,bool> filterDict)
        {
            bool isFilter = false;
            foreach (string key in filterDict.Keys)
            {
                if (dirName.Equals(key))
                {
                    isFilter= filterDict[key];
                    break;
                }
            }
            return isFilter;
        }
        private bool IsSystemFile(string fileName)
        { // 判断文件是否是系统文件
            bool isSystem = false;
            FileInfo fileInfo = new FileInfo(fileName);
            string fullName = fileInfo.FullName;
            if (fullName.StartsWith(@"C:\Windows", StringComparison.OrdinalIgnoreCase) || 
                fullName.StartsWith(@"C:\Program Files", StringComparison.OrdinalIgnoreCase) ||
                fullName.StartsWith(@"C:\Program Files (x86)", StringComparison.OrdinalIgnoreCase)||
                fullName.StartsWith(@"C:\$Recycle.Bin", StringComparison.OrdinalIgnoreCase))
                //fullName.StartsWith(@"C:\$WinREAgent", StringComparison.OrdinalIgnoreCase)||
                //fullName.StartsWith(@"C:\AMD", StringComparison.OrdinalIgnoreCase)||
                //fullName.StartsWith(@"C:\db", StringComparison.OrdinalIgnoreCase)||
                //fullName.StartsWith(@"C:\ProgramData", StringComparison.OrdinalIgnoreCase)||
                //fullName.StartsWith(@"C:\Qt6.7", StringComparison.OrdinalIgnoreCase))
            {
                isSystem = true;
            }
            return isSystem;
        }
        private void PreScanDisk(string driveLetter, List<FileInfo> files,Dictionary<string,bool> filterDict,Common.Options options)
        {
            // 预扫描磁盘，规避系统文件和删除空文件夹
            files.AddRange(new DirectoryInfo(driveLetter).GetFiles());
            string[] dirs = Directory.GetDirectories(driveLetter, "*.*", SearchOption.TopDirectoryOnly);
            foreach (string dir in dirs)
            {
                if (!IsSystemFile(dir) && !IsFilterDir(dir,filterDict))
                {
                    RecursiveGetFiles(new DirectoryInfo(dir), files,options);
                }
            }
        }
        public string[] GetDirs(string driveLetter)
        {
            return Directory.GetDirectories(driveLetter, "*.*", SearchOption.TopDirectoryOnly);
        }
    }
}
